package model.data.tableModel.sale;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import enums.Status;
import model.data.interfaces.IWriteableToDB;
import model.data.tableModel.TableControl;
import model.handler.databaseHandling.QueryFactory;

/**
 * Representation of the table Purchasecontainsproduct.
 * <p>
 * Contains information which <code>Product</code> is contained by a specific
 * <code>Purchase</code> and how many of them. version %I%, %G%
 * 
 * @see Product
 * @see Purchase
 */
public final class PurchaseContainsProduct implements IWriteableToDB {

	private final static Logger debug = LogManager.getLogger("DEBUG");

	private final int pcpID;
	private final Purchase Purchase;
	private final Product prod;
	private int quantity;
	private Status status;

	/**
	 * Private constructor. Objects of this class must be initialized by the
	 * factory methods.
	 * 
	 * @param id
	 * @param purchase
	 * @param prod
	 * @param quantity
	 * @param status
	 */
	private PurchaseContainsProduct(int pcpID, Purchase purchase, Product prod, int quantity, Status status) {
		assert pcpID >= 0;
		assert purchase != null;
		assert prod != null;

		this.pcpID = pcpID;
		this.Purchase = purchase;
		this.prod = prod;
		this.status = status;
		this.quantity = quantity;
	}

	/**
	 * Creates an existing PurchaseContainsProduct by data fetched from the
	 * database.
	 * 
	 * @param Purchase
	 * @param prod
	 * @param quantity
	 * @param status
	 * @return
	 */
	public static PurchaseContainsProduct createNewPurchaseContainsProduct(Purchase Purchase, Product prod, int quantity, Status status) {
		int id = TableControl.getCentralCounter();
		debug.debug("New PurchaseContainsProduct created ID: " + id);
		return new PurchaseContainsProduct(id, Purchase, prod, quantity, status);
	}

	/**
	 * Creates a new PurchaseContainsProduct.
	 * 
	 * @param id
	 * @param Purchase
	 * @param prod
	 * @param quantity
	 * @param status
	 * @return
	 */
	public static PurchaseContainsProduct createExistingPurchaseContainsProduct(int id, Purchase Purchase, Product prod, int quantity, Status status) {
		debug.debug("Existing PurchaseContainsProduct created ID: " + id);
		return new PurchaseContainsProduct(id, Purchase, prod, quantity, status);
	}

	@Override
	public boolean writeToDB() {
		debug.info("PCP written to DB ID: " + pcpID);
		prod.writeUpdateToDB();
		return QueryFactory.writePurchaseContainsProductToDB(pcpID, Purchase.getPurchaseID(), prod.getID(), quantity, status);
	}

	@Override
	public boolean writeUpdateToDB() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int hashCode() {

		final int prime = 31;
		int result = 1;
		result = prime * result + pcpID;
		result = prime * result + ((Purchase == null) ? 0 : Purchase.hashCode());
		result = prime * result + ((prod == null) ? 0 : prod.hashCode());
		result = prime * result + quantity;
		return result;
	}

	@Override
	public boolean equals(Object obj) {

		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		PurchaseContainsProduct other = (PurchaseContainsProduct) obj;
		if (pcpID != other.pcpID)
			return false;
		if (Purchase == null) {
			if (other.Purchase != null)
				return false;
		} else if (!Purchase.equals(other.Purchase))
			return false;
		if (prod == null) {
			if (other.prod != null)
				return false;
		} else if (!prod.equals(other.prod))
			return false;
		if (quantity != other.quantity)
			return false;
		return true;
	}
	
	/* GETTER AND SETTER BELOW */	

	public Purchase getPurchase() {
		return Purchase;
	}

	public Product getProd() {
		return prod;
	}

	public int getQuantity() {
		return quantity;
	}

	public Status isStatus() {
		return status;
	}
	
	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}
}
